/*    Copyright 2010 Tobias Marschall
 *
 *    This file is part of MoSDi.
 *
 *    MoSDi is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    MoSDi is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with MoSDi.  If not, see <http://www.gnu.org/licenses/>.
 */

package mosdi.index;

import java.util.Arrays;

/** Class able to calculate per node sum and maximum statistics on a position specific 
 *  score during construction of a suffix tree. */
public class ScoreIndexCalculator implements SuffixTree.NodeConstructionListener {

	private int[] scores;
	private int[] scoreMaximumAnnotation;
	private int[] scoreSumAnnotation;
	private int nodeCount;
	
	
	public ScoreIndexCalculator(int[] scores, int patternLength) {
		this.nodeCount = 0;
		// convert to sum scores
		this.scores = new int[scores.length];
		for (int i=0; i<=scores.length-patternLength; ++i) {
			int score = 0;
			for (int j=i; j<i+patternLength; ++j) {
				if (scores[j]>=0) score+=scores[j];
				else {
					score = 0;
					break;
				}
			}
			this.scores[i] = score;
		}
	}

	@Override
	public void initialize(int maxNodeCount) {
		this.scoreMaximumAnnotation = new int[maxNodeCount];
		this.scoreSumAnnotation = new int[maxNodeCount];
	}

	@Override
	public void nodeConstructed(int[] suffixStartPositions, int lcp, int parentLcp) {
		int sum = 0;
		int max = 0;
		for (int i : suffixStartPositions) {
			max = Math.max(max, scores[i]);
			if (sum==-1) continue;
			sum += scores[i];
			if (sum<0) sum = -1;
		}
		scoreSumAnnotation[nodeCount] = sum;
		scoreMaximumAnnotation[nodeCount] = max;
		nodeCount += 1;
	}

	@Override
	public void allNodesConstructed() {
		scores = null;
		scoreSumAnnotation = Arrays.copyOf(scoreSumAnnotation, nodeCount);
		scoreMaximumAnnotation = Arrays.copyOf(scoreMaximumAnnotation, nodeCount);
	}

	public int[] getScoreMaximumAnnotation() {
		return scoreMaximumAnnotation;
	}

	/** Array giving (for each node) the score sum of all substrings represented by this node.
	 *  If the score sum is out of range of int, a the respective array entry contains -1. */
	public int[] getScoreSumAnnotation() {
		return scoreSumAnnotation;
	}

}
